<?xml version="1.0" encoding="UTF-8"?>
<html lang="ja">

<head>
<link rev="MADE" href="mailto:vavivavi@yahoo.co.jp" />
<link rel="INDEX" href="orverview.html" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<link rel="stylesheet" type="text/css" href="../../../../vavi.css" />
<title>vavi.sound.adpcm.ym2608</title>
<!--
 * Copyright (c) 2003 by Naohide Sano, All rights reserved.
 *
 * Written by Naohide Sano
 *
 * @author	<a href="mailto:vavivavi@yahoo.co.jp">Naohide Sano</a> (nsano)
 *
 * @version	0.00	030823	nsano	initial version
-->
</head>

<body>

<p>
YAMAHA (YM2608) ADPCM フォーマット関連のクラスを提供します．
</p>

完成(たぶん)

<h2>これから実装すること</h2>

<ul>
<li><del>なんか音がちっちゃーい</del></li>
<li><del>OutputStream</del></li>
<li>C のリファレンスのほうがおかしい encode の i = のあたりが &gt; 0 になることがある</li>
</ul>

<h2>一次ライセンス</h2>
<ul>
<li>記載なし</li>
</ul>

<h2>ADPCMの基礎知識、およびYM2608のADPCM仕様</h2>

<blockquote cite="view-source:http://hackipedia.org/Platform/Sega/Genesis/hardware,%20FM%20synthesis,%20YM2608/html/adpcm.html">

<h3>◆ ADPCM</h3>
<p>
ADPCMはMPEGと違い、リニアPCMデータに対して1サンプルの振幅情報を圧縮する方式である。
ADPCMはサンプル間の差分を用いてデータ圧縮を行うという基本は変わらないが、コーデックの種類は多数存在し、YM2608のADPCM仕様もそのコーデックの1つである。
多くのコーデックは1サンプルのデータを2～4ビットに変換し、このADPCM化されたデータは完全に元の波形に戻る事は無く、コーデックの性能は「元波形の再現性」に現れる。
</p>
<p>
16ビットのリニアPCMの場合、前サンプルとの差分を表現するには最大16ビット分の情報が必要となるが、これをそのまま記録(DPCM形式)したのではデータを小さくする事ができない。
そこでADPCMは「差分の精度を犠牲」にする事でデータを圧縮する。
具体的にはステップサイズをコーデックのエンコード演算ルールに従い動的変化させ、各差分値を2～4ビットの精度へ変換する処理である。
</p>
<p>
たとえばYM2608のADPCMでは4ビットの情報を持つので、ステップサイズにて分割された予測される振幅値は16種類存在する。
差分の正負で半分に分かれる為、実際に適用する予測値は8種類になり、エンコーダはこの8種類の予測値にもっとも近い場所を選びだす。
さらにこのうち2点の予測値は、よりLowerかよりHigherな予測値範囲外の意味として扱われるため、もっとも誤差の小さい予測値は6種類になる。
このように実際の差分値と予測値を比較しながら4ビットの値に変換処理を行うのがADPCMエンコードである。
</p>
<p>
ステップサイズとは1サンプルの分解能幅の事であり、ステップサイズが1の16ビットPCMは0～65535の65536段階で表現する。
ステップサイズが4の16ビットPCMは下位2ビットが0である0x0000～0xFFFCの16384段階で表現する。
ステップサイズが8192の場合、下位12ビットを0にした0x0000～0xF000の16段階で表現する。
強引な表現では、8ビットPCMはステップサイズが256の16ビットPCMという表現も可能である(ただし記録する範囲は上位8ビットだが)。
ステップサイズは量子化幅とも呼ばれる。
</p>
<p>
この為、ステップサイズを小さい値から大きい値に変換(ADPCMエンコード)した場合、差分値とステップサイズの境界値との誤差が大きいほど波形精度が悪くなる。
またステップサイズを元に戻す変換(ADPCMデコード)をした場合も、落とされた精度分の情報を再現する事ができない。
これが「元波形の再現性」と「差分の精度を犠牲」にするという意味である。
</p>
<p>
ステップサイズの動的変更は、各サンプル毎のコーデックエンコード演算によって更新される。
これはステップサイズまでデータとして記録すると、データ圧縮として効率的で無くなる為である。
エンコードの際に、元波形に対する適切なステップサイズが適宜使用されれば、その変換精度をなるべく高く保つ事が可能である。
これはそのエンコーダと、その波形予測ルールが優秀であるほど、ADPCM化されたデータの復元率が高くなる事を表す。
</p>
<!--
<p>
ADPCMはMPEGと違いリアルタイムエンコード時のレイテンシーの低さが特徴である。
MPEG形式の周波数帯域圧縮はある一定時間(512サンプル)のサンプリングデータに対して圧縮しなければならない。
これに対してADPCMは、1～3サンプル程度のデータから圧縮が可能であり、音声通信によるレイテンシを大きく下げる事が可能である。
</p>
-->

<h3>◆ エンコード</h3>
<p>
YM2608のADPCMアルゴリズムは比較的単純である。
YM2608のADPCMは16ビットのPCMを4ビットのADPCMデータに変換する。
またステップサイズは1/4単位の線形範囲による境界となる。
以下にこのエンコード手順を記載する。
</p>
<ol>
<li>最初のサンプル X1 の取得と共に、予測値とステップサイズを初期化する。
予測値の初期値 x0=0、ステップサイズの初期値 S0=127である。</li>

<li>ADPCMデータ An を求めるには Xn と予測値 xn の差を演算し、差分 ⊿n を求める。</li>

<li>⊿n の絶対値を Sn で分割し( I=|⊿n|/Sn )、以下の表のようにIの演算結果から下位3ビットを決定する。<br/>
<div align="center">
<table class="ltb" border="1" cellpadding="2" cellspacing="0">
<tbody><tr><td>An</td><td>L3</td><td>L2</td><td>L1</td><td>I=|⊿n|/Sn</td><td>f</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>I &lt; 1/4</td><td>57/64</td></tr>
<tr><td>1</td><td>0</td><td>0</td><td>1</td><td>1/4 &lt;= I &lt; 2/4</td><td>57/64</td></tr>
<tr><td>2</td><td>0</td><td>1</td><td>0</td><td>2/4 &lt;= I &lt; 1/4</td><td>57/64</td></tr>
<tr><td>3</td><td>0</td><td>1</td><td>1</td><td>3/4 &lt;= I &lt; 4/4</td><td>57/64</td></tr>
<tr><td>4</td><td>1</td><td>0</td><td>0</td><td>4/4 &lt;= I &lt; 5/4</td><td>77/64</td></tr>
<tr><td>5</td><td>1</td><td>0</td><td>1</td><td>5/4 &lt;= I &lt; 6/4</td><td>102/64</td></tr>
<tr><td>6</td><td>1</td><td>1</td><td>0</td><td>6/4 &lt;= I &lt; 7/4</td><td>128/64</td></tr>
<tr><td>7</td><td>1</td><td>1</td><td>1</td><td>7/4 &lt;= I</td><td>153/64</td></tr>
</tbody></table>
</div>
<p>
⊿n と Sn の分割値 I が1/4以上かつ2/4未満であれば An は1というように求める。
つまり実際の差分が予測ステップサイズを超える精度になった場合(1/4未満や7/4以上)、予測値を大きく外れている可能性があり、これはデータ再現性に影響が出始める事を表す。
</p>
</li>
<li>⊿n が正の場合は An の最上位ビット(ビット4)を0、負の場合は1にする。</li>

<li>予測値 x(n+1) を求める。予測値の更新には An の各ビット値と以下の式を用いて求める。<br/>
<div align="center">
x(n+1) = ( 1-2xL4 ) x ( L3 + L2/2 + L1/4 + 1/8 ) x ⊿n + xn
</div>
</li>

<li>ステップサイズ S(n+1) を求める。ステップサイズの更新には、An の下位3ビットと上記表の f との関係を用いて求める。<br/>
<div align="center">
S(n+1) = f( An ) x Sn
</div>
</li>

<li>ステップサイズ Sn を飽和する。YM2608のADPCMステップサイズは最小127、最大24576と決められている。</li>

<li>データの終端まで2～7を繰り返す。</li>
</ol>

<h3>◆ デコード</h3>
<p>
エンコードの5と6が予測値とステップサイズを求める式となり、予測値 xn が復元値 Xn になる。
</p>
<ol>
<li>最初のADPCMサンプル A1 の取得と共に、予測値とステップサイズを初期化する。
予測値の初期値 x0=0、ステップサイズの初期値 S0=127である。</li>

<li>予測値 x(n+1) を求める。予測値の更新にはエンコード同様 An の各ビット値と表を用いて求める。</li>

<li>予測値 x(n+1) を復元値 X(n) とする。</li>

<li>復元値 X(n) を-32768～32767の範囲に適宜クリッピングする。</li>

<li>ステップサイズ S(n+1) を求める。ステップサイズの更新には、An の下位3ビットと上記表の f との関係を用いて求める。</li>

<li>ステップサイズ S(n+1) を飽和する。YM2608のADPCMステップサイズは最小127、最大24576と決められている。</li>

<li>ADPCMデータの終端まで2～6を繰り返す。</li>
</ol>
</blockquote>

</body>

</html>
